#pragma once

class Timer
{
public:
	Timer(void);
	

	void	Reset();
	double	Tick();						// Returns _dt in seconds, 
										// clamped to be between _mindt, _maxdt
	double	ElapsedSeconds();
	double	UpdatesPerSecond()const;	// Rolling average of last sixty or so 1/_dt.

	// Because of the rolling average, we don't require you be exactly at
	// the _mindt, being near it is enough.  How near?  Well, let's say 90%
	// is close enough.  
	bool	RunningNearMaxSpeed()const
	{	return UpdatesPerSecond() > 0.92 * (1.0/m_mindt);	}
	bool	RunningNearMinSpeed()const
	{	return UpdatesPerSecond() < 1.1 * (1.0/m_maxdt);	}


private:
	
	double	m_dt;		// True time interval per update in seconds, 
						// can exceed _maxdt
	double	m_mindt;	// Shortest _dt to return in tick(), default 0.01
	double	m_maxdt;	// longest time to return in tick(), default 0.1

	BOOL	m_highPerformanceFlag;	// using high performance timer?

	/*
	 *	High-resolution performance counter variables
	 */ 
	double	m_cyclesPerSecond;
	LARGE_INTEGER m_lgintStartUpdate;
	LARGE_INTEGER m_lgintStartTimer;
	LARGE_INTEGER m_lgintFinish;

	double LargeIntToDouble(LARGE_INTEGER lg);

	/*
	 *	Non high-resolution performance counter variables
	 */
	unsigned long m_startUpdate;
	unsigned long m_startTimer;
	unsigned long m_finish;




public:
	void SetMinDt(double mindt);
	void SetMaxDt(double maxdt);
		
	double	GetDT() const
	{	return m_dt;	}	//Time since last update in seconds.
	BOOL	GetHighPerformanceFlag() const 
	{	return m_highPerformanceFlag;	}
	double GetMinDt() const 
	{	return m_mindt;	}
	double GetMaxDt() const
	{	return m_maxdt;	}
};
